﻿#include "TreeSpritesPass.h"

#include "../../../Common/Singleton.h"
#include "../ResourceManager/Dx2GeometryManager.h"
#include "../ResourceManager/Dx2MaterialManager.h"
#include "../ResourceManager/Dx2ShaderAndLayoutManager.h"
#include "../ResourceManager/Dx2RootSignatureManager.h"

void TreeSpritesPass::BuildRenderItems(std::vector<std::unique_ptr<RenderItem>>& allRitems,UINT& lastObjIndex)
{
    auto treeSpritesRitem = std::make_unique<RenderItem>();
    treeSpritesRitem->World = MathHelper::Identity4x4();
    treeSpritesRitem->TexTransform = MathHelper::Identity4x4();
    treeSpritesRitem->ObjCBIndex = lastObjIndex;
    lastObjIndex++;
    treeSpritesRitem->Mat = Singleton<Dx2MaterialManager>::Instance()->GetMaterial("treeSprites").get();
    treeSpritesRitem->Geo = Singleton<Dx2GeometryManager>::Instance()->GetGeometry("treeSpritesGeo").get();
    treeSpritesRitem->PrimitiveType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
    treeSpritesRitem->IndexCount = treeSpritesRitem->Geo->DrawArgs["points"].IndexCount;
    treeSpritesRitem->StartIndexLocation = treeSpritesRitem->Geo->DrawArgs["points"].StartIndexLocation;
    treeSpritesRitem->BaseVertexLocation = treeSpritesRitem->Geo->DrawArgs["points"].BaseVertexLocation;

    mRenderItems.push_back(treeSpritesRitem.get());
    allRitems.push_back(move(treeSpritesRitem));   
}

void TreeSpritesPass::BuildPSOs(ID3D12Device* device, DXGI_FORMAT BackBufferFormat, DXGI_FORMAT DepthStencilFormat,
    bool _4xMsaaState, UINT _4xMsaaQuality)
{
    D3D12_GRAPHICS_PIPELINE_STATE_DESC treeSpritePsoDesc;
    ZeroMemory(&treeSpritePsoDesc,sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
	
    treeSpritePsoDesc.InputLayout = {Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetTreeInputLayout().data(),(UINT)Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetTreeInputLayout().size()};
    treeSpritePsoDesc.pRootSignature = Singleton<Dx2RootSignatureManager>::Instance()->GetRootSignature(RootSignatureType::Default).Get();
	
    treeSpritePsoDesc.VS =
          {
        reinterpret_cast<BYTE*>(Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpriteVS")->GetBufferPointer()),
        Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpriteVS")->GetBufferSize()
    };
    treeSpritePsoDesc.GS =
        {
        reinterpret_cast<BYTE*>(Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpriteGS")->GetBufferPointer()),
        Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpriteGS")->GetBufferSize()
        };
    treeSpritePsoDesc.PS =
    {
        reinterpret_cast<BYTE*>(Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpritePS")->GetBufferPointer()),
        Singleton<Dx2ShaderAndLayoutManager>::Instance()->GetShader("treeSpritePS")->GetBufferSize()
        };
	
    treeSpritePsoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
    treeSpritePsoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
    treeSpritePsoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
    treeSpritePsoDesc.SampleMask = UINT_MAX;
    treeSpritePsoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
    treeSpritePsoDesc.NumRenderTargets = 1;
    treeSpritePsoDesc.RTVFormats[0] = BackBufferFormat;
    treeSpritePsoDesc.SampleDesc.Count = _4xMsaaState? 4:1;
    treeSpritePsoDesc.SampleDesc.Quality = _4xMsaaState? (_4xMsaaQuality - 1):0;
    treeSpritePsoDesc.DSVFormat = DepthStencilFormat;

    treeSpritePsoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
    treeSpritePsoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;

    ThrowIfFailed(device->CreateGraphicsPipelineState(&treeSpritePsoDesc,IID_PPV_ARGS(&mPso)));
}

void TreeSpritesPass::Draw(ID3D12GraphicsCommandList* cmdList, CD3DX12_GPU_DESCRIPTOR_HANDLE hGpuHandler,
    UINT srvHeapSize, UINT objCBByteSize, UINT matCBByteSize, UINT passCBByteSize,
    ID3D12Resource* objectCB,ID3D12Resource* matCB, ID3D12Resource* passCB,
    const PassConstants& passValue,
    ID3D12Resource* OutColorRenderTarget,
    D3D12_CPU_DESCRIPTOR_HANDLE OutColorRenderTargetView,
    D3D12_CPU_DESCRIPTOR_HANDLE OutDepthStentilView
 
    )
{
    cmdList->SetPipelineState(mPso.Get());
    DrawRenderItem(cmdList,hGpuHandler,srvHeapSize,objCBByteSize,matCBByteSize,objectCB,matCB,mRenderItems);
}
